package com.sc.nft.helper;


import com.sc.nft.dao.CollectionChainInitDetailsLogDaoImpl;
import org.springframework.context.ApplicationContext;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.sc.nft.constant.TableNameConstants.*;

/**
 * 表分区路由控制器，用于精细化控制表路由
 *
 * @author zlikun
 * @since 2024/06/24
 */
public class TablePartitionRouter {

    private static final ConcurrentMap<String, Router> CACHE = new ConcurrentHashMap<>();

    public static Router ofCollectionChainInitDetailsLogRouter() {
        ApplicationContext context = ApplicationContextHolder.getContext();
        return CACHE.computeIfAbsent(COLLECTION_CHAIN_INIT_DETAILS_LOG,
                (table) -> new CollectionChainInitDetailsLogDaoImpl.CollectionChainInitDetailsLogRouter(context));
    }

    public static Router ofUserWalletDetail() {
        return CACHE.computeIfAbsent(USER_WALLET_DETAIL, (table) -> new Router() {
        });
    }

    public static Router ofExpenditureRecord() {
        return CACHE.computeIfAbsent(EXPENDITURE_RECORD, (table) -> new Router() {
        });
    }


    public interface Router {

        /**
         * 主键路由，默认取截断 100_000_000 后的固定2位数
         *
         * @param pk 主键
         * @return 返回分片标识（表后缀），NULL表示走默认路由
         */
        default String routeWithPk(Number pk) {
            return TableIdGenerator.partition(pk.longValue());
        }

        /**
         * 字段路由，默认取模100，取值区间 [00, 99]
         *
         * @param field 字段值
         * @return 返回分片标识（表后缀），NULL表示走默认路由
         */
        default String routeWithField(Number field) {
            return String.format("%02d", field.longValue() % 100);
        }

        /**
         * @return 返回所有分片标识（表后缀），默认：100片 [00, 99]
         */
        default List<String> parts() {
            return IntStream.range(0, 100).mapToObj(i -> String.format("%02d", i)).collect(Collectors.toList());
        }
    }

}
